package com.nbjtjc.safe.service.emg;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.mapper.emg.EmgPlanGoodsMapper;
import com.nbjtjc.safe.mapper.emg.EmgPlanMapper;
import com.nbjtjc.safe.mapper.emg.EmgTypeMapper;
import com.nbjtjc.safe.mapper.emg.handle.EmgHandleGoodsMapper;
import com.nbjtjc.safe.mapper.emg.handle.EmgHandleListMapper;
import com.nbjtjc.safe.mapper.emg.handle.EmgHandleMapper;
import com.nbjtjc.safe.model.emg.EmgPlan;
import com.nbjtjc.safe.model.emg.EmgPlanGoods;
import com.nbjtjc.safe.model.emg.EmgType;
import com.nbjtjc.safe.model.emg.handle.EmgHandle;
import com.nbjtjc.safe.model.emg.handle.EmgHandleGoods;
import com.nbjtjc.safe.model.emg.handle.EmgHandleList;
import com.nbjtjc.safe.util.MyShiroUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class EmgTypeService {

    @Autowired
    private EmgTypeMapper emgTypeMapper;

    @Autowired
    private EmgPlanMapper emgPlanMapper;

    @Autowired
    private EmgPlanGoodsMapper emgPlanGoodsMapper;
    @Autowired
    private EmgHandleListMapper emgHandleListMapper;
    @Autowired
    private EmgHandleGoodsMapper emgHandleGoodsMapper;
    @Autowired
    private EmgHandleMapper emgHandleMapper;
    public List<EmgType> getAll(int companyId){
        EmgType emgType=new EmgType();
        emgType.setParentId(0);
        emgType.setCompanyId(companyId);
        List<EmgType> topTypes=emgTypeMapper.select(emgType);
        if(CollectionUtil.isNotEmpty(topTypes)){
            getSubType(topTypes);
        }
        return topTypes;
    }
    public Result getPath(int typeId) {
        Result result = new Result();
        Stack<Integer> stack = new Stack<>();
        stack=path(stack,typeId);
        result.setData(ArrayUtil.reverse(stack.toArray()));
        return result;
    }

    private Stack<Integer> path(Stack<Integer> stack, int typeId) {
        stack.push(typeId);
        EmgType emgType = emgTypeMapper.selectByPrimaryKey(typeId);
        if (ObjectUtil.isNotNull(emgType)) {
            if(ObjectUtil.isNotNull(emgType.getParentId())
                    && emgType.getParentId().equals(0)){
                return stack;
            }else{
                path(stack,emgType.getParentId());
            }
        }
        return stack;
    }
    public List<EmgType> find(EmgType emgType){
        List<EmgType> emgTypes=new ArrayList<>();
        emgTypes=emgTypeMapper.search(emgType);
        return emgTypes;
    }

    /**
     * 复制应急响应类型的结构，同时复制相对应的分类下面的应急预案的表和表中的检查条例
     * @param fromCompanyId
     * @param toCompanyId
     * @return
     */
    @Transactional
    public Boolean copyEmgType(int fromCompanyId,int toCompanyId){
        EmgType emgType=new EmgType();
        emgType.setCompanyId(fromCompanyId);
        List<EmgType> emgTypes=emgTypeMapper.searchWithPlan(emgType);
        if(CollectionUtil.isEmpty(emgTypes)){
            return true;
        }
        Map<Integer,List<EmgType>> parentIdMap=new HashedMap();
        emgTypes.forEach(type->{
            if(parentIdMap.containsKey(type.getParentId())){
                parentIdMap.get(type.getParentId()).add(type);
            }else{
                List<EmgType> emgTypeList=new ArrayList<>();
                emgTypeList.add(type);
                parentIdMap.put(type.getParentId(),emgTypeList);
            }
        });
        List<EmgType> topTypes=new ArrayList<>();
        if(parentIdMap.containsKey(0)){
            topTypes=parentIdMap.get(0);
            compareSubType(topTypes,parentIdMap);
        }
        List<EmgType> copyEmgTypes=new ArrayList<>();
        topTypes.forEach(fromType->{
            EmgType toType=new EmgType();
            toType.setCompanyId(toCompanyId);
            toType.setTypeName(fromType.getTypeName());
            toType.setParentId(0);
            toType.setEmgPlanList(fromType.getEmgPlanList());
            toType.setEmgHandles(fromType.getEmgHandles());
            constructEmgType(fromType,toType,toCompanyId);
            copyEmgTypes.add(toType);
        });
        insertEmgTyps(copyEmgTypes);
        //复制应急响应类型下面的表和关联的物资
        List<EmgPlan> copyEmgPlans=new ArrayList<>();
        //复制的应急处置下类型的表和关联的物资和handleList
        List<EmgHandle> copyEmgHandles=new ArrayList<>();
        copyEmgTypes.forEach(type->{
            if(CollectionUtil.isNotEmpty(type.getEmgPlanList())){
                type.getEmgPlanList().forEach(fromPlan->{
                    EmgPlan toPlan=fromPlan.copyType();
                    toPlan.setCompanyId(type.getCompanyId());
                    toPlan.setTypeId(type.getId());
                    toPlan.setTopTypeId(type.getId());
                    toPlan.setEmgPlanGoods(fromPlan.getEmgPlanGoods());
                    copyEmgPlans.add(toPlan);
                });
            }
            if(CollectionUtil.isNotEmpty(type.getEmgHandles())){
                type.getEmgHandles().forEach(fromHandle->{
                    EmgHandle toHandle=new EmgHandle();
                    toHandle.setCompanyId(toCompanyId);
                    toHandle.setTypeId(type.getId());
                    toHandle.setTopTypeId(type.getId());
                    toHandle.setEventLevel(fromHandle.getEventLevel());
                    toHandle.setName(fromHandle.getName());
                    toHandle.setRemark(fromHandle.getRemark());
                    toHandle.setCreateTime(new Date());
                    toHandle.setDeptId(MyShiroUtils.getDeptId());
                    toHandle.setEmgHandleGoodsList(fromHandle.getEmgHandleGoodsList());
                    copyEmgHandles.add(toHandle);
                });
            }
            if(CollectionUtil.isNotEmpty(type.getSubTypes())){
                copyEmgPlanAndHandle(type.getSubTypes(),type.getId(),copyEmgPlans,copyEmgHandles);
            }
        });
        if(CollectionUtil.isNotEmpty(copyEmgPlans)){
            emgPlanMapper.insertList(copyEmgPlans);
        }
        if(CollectionUtil.isNotEmpty(copyEmgHandles)){
            emgHandleMapper.insertList(copyEmgHandles);
        }
        insertPlanGoods(copyEmgPlans);
        insertHandleGoods(copyEmgHandles);
        insertHandleList(copyEmgHandles);
        return true;
    }


    /**
     * 插入应急处置关联的物资
     * @param copyHandles
     */
    private void insertHandleGoods(List<EmgHandle> copyHandles){
        List<EmgHandleGoods> emgHandleGoodsList=new ArrayList<>();
        copyHandles.forEach(emgHandle -> {
            if(CollectionUtil.isNotEmpty(emgHandle.getEmgHandleGoodsList())){
                emgHandle.getEmgHandleGoodsList().forEach(emgHandleGoods -> {
                    EmgHandleGoods copyGoods=new EmgHandleGoods();
                    copyGoods.setName(emgHandleGoods.getName());
                    copyGoods.setHandleId(emgHandle.getId());
                    emgHandleGoodsList.add(copyGoods);
                });
            }
        });
        if(CollectionUtil.isNotEmpty(emgHandleGoodsList)){
            emgHandleGoodsMapper.insertList(emgHandleGoodsList);
        }
    }

    /**
     * 插入应急预案关联的物资
     * @param emgPlans
     */
    private void insertPlanGoods(List<EmgPlan> emgPlans){
        List<EmgPlanGoods>  insertPlanGoods=new ArrayList<>();
        emgPlans.forEach(emgPlan -> {
            List<EmgPlanGoods> emgPlanGoods=emgPlan.getEmgPlanGoods();
            if(CollectionUtil.isNotEmpty(emgPlanGoods)){
                emgPlanGoods.forEach(planGoods->{
                    planGoods.setPlanId(emgPlan.getId());
                    insertPlanGoods.add(planGoods);
                });
            }
        });
        if(CollectionUtil.isNotEmpty(insertPlanGoods)){
            emgPlanGoodsMapper.insertList(insertPlanGoods);
        }
    }

    /**
     * 将类型下的应急预案和应急处置复制到 copyEmgPlans 和 emgHandles
     * @param emgTypeList
     * @param topId
     * @param copyEmgPlans
     * @param emgHandles
     */
    private void copyEmgPlanAndHandle(List<EmgType> emgTypeList,int topId
            ,List<EmgPlan> copyEmgPlans,List<EmgHandle> emgHandles){
        emgTypeList.forEach(emgType -> {
            if(CollectionUtil.isNotEmpty(emgType.getEmgPlanList())){
                emgType.getEmgPlanList().forEach(fromPlan->{
                    EmgPlan toPlan=fromPlan.copyType();
                    toPlan.setCompanyId(emgType.getCompanyId());
                    toPlan.setTypeId(emgType.getId());
                    toPlan.setTopTypeId(topId);
                    toPlan.setEmgPlanGoods(fromPlan.getEmgPlanGoods());
                    copyEmgPlans.add(toPlan);
                });
            }
            if(CollectionUtil.isNotEmpty(emgType.getEmgHandles())){
                emgType.getEmgHandles().forEach(fromHandle->{
                    EmgHandle toHandle=new EmgHandle();
                    toHandle.setCompanyId(emgType.getCompanyId());
                    toHandle.setTypeId(emgType.getId());
                    toHandle.setTopTypeId(emgType.getId());
                    toHandle.setEventLevel(fromHandle.getEventLevel());
                    toHandle.setName(fromHandle.getName());
                    toHandle.setRemark(fromHandle.getRemark());
                    toHandle.setCreateTime(new Date());
                    toHandle.setDeptId(MyShiroUtils.getDeptId());
                    toHandle.setEmgHandleGoodsList(fromHandle.getEmgHandleGoodsList());
                    toHandle.setEmgHandleLists(fromHandle.getEmgHandleLists());
                    emgHandles.add(toHandle);
                });
            }
            if(CollectionUtil.isNotEmpty(emgType.getSubTypes())){
                copyEmgPlanAndHandle(emgType.getSubTypes(),topId,copyEmgPlans,emgHandles);
            }
        });
    }

    /**
     * 插入需要复制的handleList
     * @param emgHandles
     */
    private void insertHandleList(List<EmgHandle> emgHandles){
        List<EmgHandleList> emgHandleLists=new ArrayList<>();
        emgHandles.forEach(emgHandle -> {
            if(CollectionUtil.isNotEmpty(emgHandle.getEmgHandleLists())){
                emgHandle.getEmgHandleLists().forEach(fromHandleList -> {
                    EmgHandleList copyHandleList=new EmgHandleList();
                    copyHandleList.setExecContent(fromHandleList.getExecContent());
                    copyHandleList.setHelpInfo(fromHandleList.getHelpInfo());
                    copyHandleList.setNum(fromHandleList.getNum());
                    copyHandleList.setHandleId(emgHandle.getId());
                    emgHandleLists.add(copyHandleList);
                });
            }
        });
        if(CollectionUtil.isNotEmpty(emgHandleLists)){
            emgHandleListMapper.insertList(emgHandleLists);
        }
    }
    /**
     * 构建复制标签的结构，但还未插入
     *
     * @param fromType
     * @param toType
     * @param companyId
     */
    private void constructEmgType(EmgType fromType, EmgType toType, int companyId) {
        if (CollectionUtil.isNotEmpty(fromType.getSubTypes())) {
            List<EmgType> emgTypes = new ArrayList<>();
            fromType.getSubTypes().forEach(type -> {
                EmgType emgType= new EmgType();
                emgType.setTypeName(type.getTypeName());
                emgType.setCompanyId(companyId);
                emgType.setEmgPlanList(type.getEmgPlanList());
                emgType.setEmgHandles(type.getEmgHandles());
                constructEmgType(type, emgType, companyId);
                emgTypes.add(emgType);
            });
            toType.setSubTypes(emgTypes);
        }
    }

    /**
     * 按层标签结构层次插入标签
     * —2
     * 1—       —4
     * —3—
     * —5
     * 如上所示，先插入1，再插入2,3，再插入4,5，按层次插入
     */
    private void insertEmgTyps(List<EmgType> insertEmgTypes) {
        emgTypeMapper.insertList(insertEmgTypes);
        List<EmgType> toInsertTypes = new ArrayList<>();
        insertEmgTypes.forEach(type -> {
            if (CollectionUtil.isNotEmpty(type.getSubTypes())) {
                type.getSubTypes().forEach(insertType -> {
                    insertType.setParentId(type.getId());
                    toInsertTypes.add(insertType);
                });
            }
        });
        if (CollectionUtil.isNotEmpty(toInsertTypes)) {
            insertEmgTyps(toInsertTypes);
        }
    }

    private void compareSubType(List<EmgType> types,Map<Integer,List<EmgType>> parentIdMap){
        types.forEach(type->{
            if(parentIdMap.containsKey(type.getId())){
                List<EmgType> emgTypes=parentIdMap.get(type.getId());
                if(CollectionUtil.isNotEmpty(emgTypes)){
                    type.setSubTypes(emgTypes);
                    compareSubType(emgTypes,parentIdMap);
                }
            }
        });
    }

    private void getSubType(List<EmgType> emgTypes){
        emgTypes.forEach(emgType -> {
            EmgType type=new EmgType();
            type.setParentId(emgType.getId());
            List<EmgType> subTypes=emgTypeMapper.search(type);
            if(CollectionUtil.isNotEmpty(subTypes)){
                getSubType(subTypes);
                emgType.setSubTypes(subTypes);
            }
        });
    }
}
